#include <QtCore/QString>
#include <QtTest/QtTest>
#include <QDebug>
#include <stdlib.h>

#include "EncryptionManager.h"
#include "SymmetricKeyFile.h"
#include "SymmetricKeyMemory.h"
#include "PublicKey.h"
#include "SymmetricEncrypter.h"
#include "KeyGenerator.h"

using namespace kryptos::cryptography;
using namespace kryptos::entities;

class EncryptionManagerTest : public QObject
{
    Q_OBJECT

public:
    EncryptionManagerTest(){}

private Q_SLOTS:

    void initTestCase();
    void cleanupTestCase();

    void encryptFile();
    void decryptFile();
    void encryptFileHybridFormat();
    void decryptFileHybridFormat();

private:

    SymmetricKeyFile keyFile, keyFileReusable;
    PrivateKey       privkey, otherPrivkey;
};

void EncryptionManagerTest::initTestCase()
{
    KeyGenerator::init();

    KeyInfo info(KeyInfo::RSA, "sebastian", "seba@mail.com", "test", "sebastian", 1024);
    info.setKeyid("1234567890123456789012345678901234567890");

    KeyInfo info2(KeyInfo::RSA, "martin", "martin@mail.com", "test", "martin", 1024);
    info2.setKeyid("mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm");

    privkey      = KeyGenerator::generateKey(info, KeyInfo::RSA);
    otherPrivkey = KeyGenerator::generateKey(info2, KeyInfo::RSA);

    keyFile.change("key.txt");
    keyFileReusable.change("key.txt", true);
}

void EncryptionManagerTest::cleanupTestCase()
{
}

void EncryptionManagerTest::encryptFile()
{
    QFile::remove("encfile.krp");

    std::vector<PublicKey> recipients;
    recipients.push_back(privkey.publicKeyPart());

    EncryptionManager manager;
    manager.encryptWithPublicKey("testfile.txt", "encfile.krp", recipients);
}

void EncryptionManagerTest::decryptFile()
{
    QFile::remove("decfile.txt");

    EncryptionManager manager;

    QCOMPARE(manager.cryptoFormat("encfile.krp"), CryptoFile::K_PK01);
    QCOMPARE((int)manager.symmetricKeyLengthNeededToDecrypt("encfile.krp"), 0);

    SymmetricKeyMemory symkey;
    int result = manager.decrypt("encfile.krp", "decfile.txt", privkey, symkey);
    QVERIFY2(result == 0, "Error decrypting file");
}

void EncryptionManagerTest::encryptFileHybridFormat()
{
    QFile::remove("encfile_hybrid.krp");

     std::vector<PublicKey> recipients;
     recipients.push_back(privkey.publicKeyPart());
     recipients.push_back(otherPrivkey.publicKeyPart());

     EncryptionManager manager;
     manager.encryptWithHybridFormat("testfile.txt", "encfile_hybrid.krp", recipients, keyFile);
}

void EncryptionManagerTest::decryptFileHybridFormat()
{
    QFile::remove("decfile_hybrid.txt");

    EncryptionManager manager;

    QCOMPARE(manager.cryptoFormat("encfile_hybrid.krp"), CryptoFile::K_OTPRSA01);
    QVERIFY((int)manager.symmetricKeyLengthNeededToDecrypt("encfile_hybrid.krp")>0);
    QCOMPARE(manager.symmetricKeyNeeded("encfile_hybrid.krp", privkey), keyFile.id());

    int result = manager.decrypt("encfile_hybrid.krp", "decfile_hybrid.txt", otherPrivkey, keyFile);
    QVERIFY2(result == 0, "Error decrypting file");
}


QTEST_MAIN(EncryptionManagerTest);

#include "EncryptionManagerTest.moc"
